const mongoclient = require('mongodb').MongoClient
const objectId = require('mongodb').ObjectID

const config = require('./module/config')

/*
    在进行封装的时候要充分的考虑性能，  比如在查找数据的签替是需要连接数据库， 在同一个实例中查找数据每次都需要
        连接一次数据库嘛？  还有在不同的实例中，如果数据库是同一个数据库也需要重新连接数据嘛  这个也是性能不高
        所以我们作为程序员，要充分的考虑性能，性能优先
*/ 

class db {

    static isconnection() {
        /*
            提高性能，  使用静态方法来实现单例模式  意思是只有一个实例化的对象
        */

        if (!db.connection) {
            // console.log('hello')
            return db.connection = new db()
        } else {
            return db.connection
        }
    }

    constructor() {
        this.status = ''
        // this.connect()
        // console.log('hellos')
    }

    /*
        在封装各个方法的时候使用promise是来进行封装是优解
    */
    connect() {
        return new Promise((reslove, reject) => {
            // console.log('55',this)
            // console.log('status:', this.status)
            if (this.status === '') {
                // console.log('第一次')
                mongoclient.connect(config.URL, { useUnifiedTopology: true }, (err, dbs) => {
                    if (err) {
                        reject('连接失败', err)
                    } else {
                        // console.log('连接成功')
                        this.status = dbs.db(config.dbName)
                        reslove(this.status)
                    }
                })
            } else {
                reslove(this.status)
            }
        })
    }

    find(collectionName, option) {
        // console.log(this.connect())
        return new Promise((reslove, reject) => {
            // 这里需要使用箭头函数才能够获取到this  因为箭头函数的this指向的是拥有这个函数的对象的this 并不是函数本身的this
            this.connect().then(res => {
                let colection = res.collection(collectionName)
                reslove(colection.find(option).toArray())
            })
        })
    }

    getObjectId(id) { 
        // console.log(id)
        return new objectId(id)
    }

    insert(collectionName, data) { 
        return new Promise((reslove, reject) => { 
            this.connect().then(res => { 
                let colection = res.collection(collectionName)
                colection.insertOne(data, (err, data) => { 
                    // console.log(data)
                    if (err) { 
                        reject('插入失败:', err)
                        return
                    }
                    reslove(data.result)
                })
            })
        })
    }

    update(collectionName,tiaojian,data) { 
        return new Promise((reslove, reject) => { 
            this.connect().then(res => { 
                let collection = res.collection(collectionName)
                collection.updateOne(tiaojian, { $set: data }, (err, data) => { 
                    if (err) { 
                        reject('更新失败:',err)
                        return
                    }
                    reslove(data.result)
                })
            })
        })
    }

    delete(collectionName, tiaojian) { 
        return new Promise((reslove, reject) => { 
            this.connect().then(res => { 
                let collection = res.collection(collectionName)
                collection.deleteOne(tiaojian, (err, data) => { 
                    if (err) { 
                        reject('删除失败:', err)
                        return
                    }
                    reslove(data.result)
                })
            })
        })
    }
}

// let dbs = db.isconnection()
// dbs.insert('koa', { name: '123', age: '123', othters: { weight: '123' } }).then(res => { 
//     console.log(res)
// }).catch(err => { 
//     console.log(err)
// })
// dbs.find('koa', '').then(data => { 
//     console.log(data)
// })

module.exports = db
